/*

YV12 chroma upsampling fixer

by Kurt Bernhard 'Leak' Pruenner



Use with YV12 output if the half-resolution chroma 

gets upsampled in hardware by doubling the values

instead of interpolating between them.



(i.e. if you're getting blocky red edges on dark 

backgrounds...)

*/



sampler s0 : register(s0);

float4 p0 : register(c0);

float4 p1 : register(c1);



#define width (p0[0])

#define height (p0[1])



float4 getPixel(float2 tex, float dx, float dy)

{

	tex.x+=dx;

	tex.y+=dy;

	

	return tex2D(s0, tex);

}



float4 rgb2yuv(float4 rgb)

{

	float4x4 coeffs=

		{

			 0.299, 0.587, 0.114, 0.000,

			-0.147,-0.289, 0.436, 0.000,

			 0.615,-0.515,-0.100, 0.000,

			 0.000, 0.000, 0.000, 0.000

		};

		

	return mul(coeffs,rgb);

}



float4 yuv2rgb(float4 yuv)

{

	float4x4 coeffs=

		{

			 1.000, 0.000, 1.140, 0.000,

			 1.000,-0.395,-0.581, 0.000,

			 1.000, 2.032, 0.000, 0.000,

			 0.000, 0.000, 0.000, 0.000

		};

	

	return mul(coeffs,yuv);

}



float4 main(float2 tex : TEXCOORD0) : COLOR

{

	float dx=1/width;

	float dy=1/height;

	

	float4 yuv00=rgb2yuv(getPixel(tex,-dx,-dy));

	float4 yuv01=rgb2yuv(getPixel(tex,-dx,  0));

	float4 yuv02=rgb2yuv(getPixel(tex,-dx, dy));

	float4 yuv10=rgb2yuv(getPixel(tex,  0,-dy));

	float4 yuv11=rgb2yuv(getPixel(tex,  0,  0));

	float4 yuv12=rgb2yuv(getPixel(tex,  0, dy));

	float4 yuv20=rgb2yuv(getPixel(tex, dx,-dy));

	float4 yuv21=rgb2yuv(getPixel(tex, dx,  0));

	float4 yuv22=rgb2yuv(getPixel(tex, dx, dy));



	float4 yuv=

		(yuv00*1+yuv01*2+yuv02*1+

		 yuv10*2+yuv11*4+yuv12*2+

		 yuv20*1+yuv21*2+yuv22*1)/16;

	

	yuv.r=yuv11.r;



	return yuv2rgb(yuv);

}